program mpi_parallel_sum
    use mpi
    implicit none

    integer, parameter :: N = 100000000  ! 总元素数 (1亿)
    integer :: ierr, rank, size, i
    
    ! 局部工作变量
    integer :: n_local, start_index, end_index 
    real(kind=8) :: local_sum, global_sum, x_val
    integer :: count_start, count_end, count_rate
    
    call MPI_INIT(ierr)
    call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)
    call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
    
    ! 1. 计算局部工作大小
    n_local = N / size
    
    ! 2. 确定每个进程的起始索引和结束索引 (全局索引)
    start_index = (rank * n_local) + 1
    end_index   = start_index + n_local - 1
    
    local_sum = 0.0d0
    
    ! 3. 局部计算 (每个进程只计算自己的那一部分)
    call system_clock(count_start, count_rate)
    do i = start_index, end_index
        ! 我们在这里直接计算值 i，而不是分配一个 800MB 的大数组 x(N) 来简化内存管理
        x_val = i * 1.0d0
        local_sum = local_sum + x_val
    end do
    call system_clock(count_end)
    
   ! 打印局部时间
    print *, "Rank ", rank, " computed sum of ", n_local, " elements in ", &
             real(count_end - count_start, kind=8) / count_rate, " seconds."
    
    ! 4. 全局收集 (下一步的关键)
    call MPI_REDUCE(local_sum, global_sum, 1, MPI_REAL8, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
    
    if (rank == 0) then
        ! 验证总和是否正确
        ! 1到N的求和公式是 N * (N + 1) / 2
        print *, "--- Verification ---"
        print *, "Theoretical Global Sum: ", real(N, kind=8) * (real(N, kind=8) + 1.0d0) / 2.0d0
        print *, "MPI Calculated Global Sum: ", global_sum
    end if

    call MPI_BARRIER(MPI_COMM_WORLD, ierr)
    call MPI_FINALIZE(ierr)
end program mpi_parallel_sum